﻿using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;


namespace XXYFramework
{
    /// <summary>
    /// UI 控制器
    /// </summary>
    public class PlayerUIControl : MonoBehaviour
    {
        [Header("按钮")]
        [SerializeField] Button JumpBtn;
        [SerializeField] Button RollBtn;
        [Header("开关")]
        [SerializeField] Button CrouchToggle;
        [SerializeField] Button ViewToggle;
        [SerializeField] Button SpeedToggle;
        [Header("摇杆")]
        [SerializeField] RectTransform movePointer;
        [SerializeField] RectTransform dirPointer;
        [Header("速度")]
        [SerializeField, Range(1, 20)] float ViewXSpeed = 10;  // 相机旋转速度
        [SerializeField, Range(1, 20)] float ViewYSpeed = 8;  // 相机旋转速度



        Character character;

        Vector2 _move;
        Vector2 _look;
        bool _isCrouch;         // 是否蹲伏
        bool _isThirdPerson;    // 是否第三人称
        bool _isAcce;          // 是否加速度
        float radius;          // 摇杆移动半径

        private void Start()
        {
            // 按钮
            JumpBtn.onClick.AddListener(OnJump);
            RollBtn.onClick.AddListener(OnRoll);

            // 开关
            CrouchToggle.onClick.AddListener(OnCrouchToggle);
            ViewToggle.onClick.AddListener(OnViewToggle);
            SpeedToggle.onClick.AddListener(OnSpeedToggle);

            character = FindObjectOfType<Character>();
            _isThirdPerson = character.isThirdPerson;
            ToggleButton(ViewToggle, _isThirdPerson);

            // 摇杆
            radius = ((RectTransform)movePointer.parent).rect.width / 2;
            EventTrigger moveEvent;
            if (!movePointer.TryGetComponent<EventTrigger>(out moveEvent))
            {
                moveEvent = movePointer.gameObject.AddComponent<EventTrigger>();
            }
            EventTrigger.Entry moveDrag = new EventTrigger.Entry();
            moveDrag.eventID = EventTriggerType.Drag;
            moveDrag.callback.AddListener(OnMovePointerDrag);
            moveEvent.triggers.Add(moveDrag);
            EventTrigger.Entry moveEndDrag = new EventTrigger.Entry();
            moveEndDrag.eventID = EventTriggerType.EndDrag;
            moveEndDrag.callback.AddListener(OnMovePointerEndDrag);
            moveEvent.triggers.Add(moveEndDrag);

            EventTrigger dirEvent;
            if (!dirPointer.TryGetComponent<EventTrigger>(out dirEvent))
            {
                dirEvent = dirPointer.gameObject.AddComponent<EventTrigger>();
            }
            EventTrigger.Entry dirDrag = new EventTrigger.Entry();
            dirDrag.eventID = EventTriggerType.Drag;
            dirDrag.callback.AddListener(OnDirPointerDrag);
            dirEvent.triggers.Add(dirDrag);
            EventTrigger.Entry dirEndDrag = new EventTrigger.Entry();
            dirEndDrag.eventID = EventTriggerType.EndDrag;
            dirEndDrag.callback.AddListener(OnDirPointerEndDrag);
            dirEvent.triggers.Add(dirEndDrag);
        }



        /// <summary>
        /// 按钮开关
        /// </summary>
        private void ToggleButton(Button button, bool isOn)
        {
            button.transform.GetChild(0).GetComponent<Image>().color = isOn ? Color.yellow : Color.white;
        }

        #region UI Function
        private void OnJump()
        {
            EJump?.Invoke();
        }
        private void OnRoll()
        {
            ERoll?.Invoke();
        }

        private void OnCrouchToggle()
        {
            if(character.GetComponent<CharacterController>().isGrounded)
            {
                _isCrouch = !_isCrouch;
                ToggleButton(CrouchToggle, _isCrouch);
                if (_isCrouch)
                {
                    ECrouchStart?.Invoke();
                }
                else
                {
                    ECrouchEnd?.Invoke();
                }
            }
        }
        private void OnViewToggle()
        {
            _isThirdPerson = !_isThirdPerson;
            ToggleButton(ViewToggle, _isThirdPerson);
            EViewToggle?.Invoke();
        }
        private void OnSpeedToggle()
        {
            _isAcce = !_isAcce;
            ToggleButton(SpeedToggle, _isAcce);
            if (_isAcce)
            {
                ESprintStart?.Invoke();
            }
            else
            {
                ESprintEnd?.Invoke();
            }
        }


        private void OnMovePointerDrag(BaseEventData arg0)
        {
            PointerEventData pointer = (PointerEventData)arg0;
            RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)movePointer.parent, pointer.position, null, out _move);
            _move -= Vector2.one * radius;
            if (_move.magnitude > radius)
            {
                _move.Normalize();
                movePointer.anchoredPosition = _move * radius;
            }
            else
            {
                movePointer.anchoredPosition = _move;
                _move /= radius;
            }
            _move.x = _move.x > 0.5f ? 1 : (_move.x < -0.5f ? -1 : 0);
            _move.y = _move.y > 0.5f ? 1 : (_move.y < -0.5f ? -1 : 0);
        }
        private void OnMovePointerEndDrag(BaseEventData arg0)
        {
            _move = Vector2.zero;
            movePointer.anchoredPosition = Vector2.zero;
        }


        private void OnDirPointerDrag(BaseEventData arg0)
        {
            PointerEventData pointer = (PointerEventData)arg0;
            RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)dirPointer.parent, pointer.position, null, out _look);
            _look.x += radius;
            _look.y -= radius;
            if (_look.magnitude > radius)
            {
                _look.Normalize();
                dirPointer.anchoredPosition = _look * radius;
            }
            else
            {
                dirPointer.anchoredPosition = _look;
                _look /= radius;
            }
        }
        private void OnDirPointerEndDrag(BaseEventData arg0)
        {
            _look = Vector2.zero;
            dirPointer.anchoredPosition = Vector2.zero;
        }
        #endregion
        #region 事件
        /// <summary>
        /// 蹲伏
        /// </summary>
        public event Action ECrouchStart;
        public event Action ECrouchEnd;
        /// <summary>
        /// 奔跑
        /// </summary>
        public event Action ESprintStart;
        public event Action ESprintEnd;
        /// <summary>
        /// 跳跃
        /// </summary>
        public event Action EJump;
        /// <summary>
        /// 翻转
        /// </summary>
        public event Action ERoll;
        /// <summary>
        /// 人称切换
        /// </summary>
        public event Action EViewToggle;

        #endregion
        #region 属性
        /// <summary>
        /// 获取 移动数值
        /// </summary>
        public Vector2 GetMoveValue
        {
            get
            {
                return _move;
            }
        }
        /// <summary>
        /// 获取 视口移动向量
        /// </summary>
        public Vector2 GetLookValue
        {
            get
            {
                return _look * new Vector2(ViewXSpeed, ViewYSpeed);
            }
        }
        /// <summary>
        /// 获取鼠标滚轮数值
        /// </summary>
        public float GetZoomValue
        {
            get
            {
                return _look.y * Time.deltaTime * 0.5f * ViewYSpeed;
            }
        }
        #endregion
    }
}